// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// K [author] rhyme_lph
// B [email]  rhymelph@gmail.com
// j [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:dio/src/response.dart';
import 'package:finance_app/src/entities/bill_entity.dart';
import 'package:finance_app/src/http_service/http_bill_service.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/page/dashboard/bill/bill_number_page.dart';

class BillNumberProvider extends BaseProvider<List<BillEntity>>
    with SearchDataListMixin, RefreshMixin<List<BillEntity>, List<BillEntity>> {
  List<BillEntity> bills = [];
  BillEntity bill;

  int filterIssueTo;

  String keyword;

  bool isSingleSelect;

  bool hideClosedBill;

  @override
  Future get dataFuture => HttpBillService.billList(page,
      status: hideClosedBill ? "open" : null,
      issue_to: filterIssueTo,
      keyword: keyword);

  void onNavAddBill() async {
    final result =
        await Routes.navigateTo(RouterGenProviders.newBillPage, params: {
      'isSelectMode': true,
    });
    if (result != null) {
      if (result is BillEntity) {
        if (filterIssueTo != null && filterIssueTo != result.contactId) {
          return;
        }
      }
      if (isSingleSelect == true) {
        bill = result;
        onDone();
      } else {
        bills.add(result);
        data.add(result);
        update();
      }
    }
  }

  void onSelect(BillEntity item1) {
    if (isSingleSelect == true) {
      bill = item1;
      onDone();
    } else {
      final result = bills.firstWhere((element) => element.id == item1.id,
          orElse: () => null);
      if (result != null) {
        bills.removeWhere((element) => element.id == item1.id);
      } else {
        bills.add(item1);
      }
      update();
    }
  }

  void onDone() {
    obtainContext?.call((context) {
      if (isSingleSelect == true) {
        Navigator.of(context).pop(bill);
      } else {
        Navigator.of(context).pop(bills);
      }
    });
  }

  void onCancel() {
    obtainContext?.call((context) {
      Navigator.of(context).pop();
    });
  }

  @override
  void searchRefreshData(string) async {
    keyword = string;
    page = 1;
    await post(refreshFuture, autoHandler: AutoHandler.Toast,
        onSuccess: (result) {
      data = getFromRequestResult(result, true);
      update();
    }, onFinally: () {
      if (data == null) {
        data = [];
      }
      update();
    });
  }

  @override
  FutureOr<List<BillEntity>> transformData(List<BillEntity> d, bool isCache) {
    List<BillEntity> updateInvoices = [];
    for (final item in d) {
      final oldItem = bills.firstWhere((element) => element.id == item.id,
          orElse: () => null);
      if (oldItem != null) {
        updateInvoices.add(item);
      }
    }
    bills = updateInvoices;

    return super.transformData(d, isCache);
  }

  @override
  List<BillEntity> get dataList => data;

  @override
  List<BillEntity> getFromRequestResult(Response result, bool isRefresh) {
    return getEntityFromResult(result);
  }

  @override
  Future get refreshFuture => dataFuture;
}
